import { create } from 'zustand';
import { multiChainApi } from '@/lib/multi-chain-api';
import { API_ENDPOINTS } from '@/config/api';
import { removeAuthToken, setAuthToken, setRefreshToken, isAuthenticated, removeAllAuthTokens, getAuthStatus } from '@/lib/auth';
import { ChainType } from '@/config/chains';

interface Admin {
  id: string;
  wallet_address: string;
  username?: string;
  email?: string;
  role: string;
  is_active: boolean;
  created_at: string;
}

interface ChainAuth {
  admin: Admin | null;
  isAuthenticated: boolean;
}

interface AuthState {
  // Store authentication state per chain
  chainAuth: Record<ChainType, ChainAuth>;
  isLoading: boolean;
  currentChain: ChainType | null;
  
  // Check if authenticated for a specific chain
  isAuthenticatedForChain: (chain: ChainType) => boolean;
  getAdminForChain: (chain: ChainType) => Admin | null;
  
  login: (walletAddress: string, signature: string, chain: ChainType) => Promise<void>;
  logout: (chain?: ChainType) => void;
  fetchAdminProfile: (chain: ChainType) => Promise<void>;
  getNonce: (walletAddress: string, chain: ChainType) => Promise<{ nonce: string; message: string }>;
  
  // Initialize auth state from cookies
  initializeAuthState: () => void;
}

const initialChainAuth: ChainAuth = {
  admin: null,
  isAuthenticated: false,
};

export const useAuthStore = create<AuthState>((set, get) => ({
  chainAuth: {
    mainnet: { ...initialChainAuth },
    testnet: { ...initialChainAuth },
  },
  isLoading: false,
  currentChain: null,
  
  isAuthenticatedForChain: (chain: ChainType) => {
    return get().chainAuth[chain]?.isAuthenticated || false;
  },
  
  getAdminForChain: (chain: ChainType) => {
    return get().chainAuth[chain]?.admin || null;
  },
  
  initializeAuthState: () => {
    const authStatus = getAuthStatus();
    const chains: ChainType[] = ['mainnet', 'testnet'];
    
    chains.forEach(async (chain) => {
      if (authStatus[chain]) {
        try {
          await get().fetchAdminProfile(chain);
        } catch (error) {
          console.error(`Failed to fetch admin profile for ${chain}:`, error);
        }
      }
    });
  },
  
  getNonce: async (walletAddress: string, chain: ChainType) => {
    const client = multiChainApi.getClient(chain);
    const response = await client.post(API_ENDPOINTS.auth.nonce, {
      wallet_address: walletAddress,
    });
    return response.data;
  },
  
  login: async (walletAddress: string, signature: string, chain: ChainType) => {
    set({ isLoading: true });
    try {
      const client = multiChainApi.getClient(chain);
      const response = await client.post(API_ENDPOINTS.auth.login, {
        wallet_address: walletAddress,
        signature,
      });
      
      const { access_token, refresh_token } = response.data;
      setAuthToken(access_token, chain);
      setRefreshToken(refresh_token, chain);
      
      // Fetch admin profile
      const profileResponse = await client.get(API_ENDPOINTS.admin.profile);
      
      set((state) => ({
        chainAuth: {
          ...state.chainAuth,
          [chain]: {
            admin: profileResponse.data,
            isAuthenticated: true,
          },
        },
        isLoading: false,
        currentChain: chain,
      }));
    } catch (error) {
      set({ isLoading: false });
      throw error;
    }
  },
  
  logout: (chain?: ChainType) => {
    if (chain) {
      // Logout from specific chain
      removeAuthToken(chain);
      set((state) => ({
        chainAuth: {
          ...state.chainAuth,
          [chain]: {
            admin: null,
            isAuthenticated: false,
          },
        },
      }));
    } else {
      // Logout from all chains
      removeAllAuthTokens();
      set({
        chainAuth: {
          mainnet: { ...initialChainAuth },
          testnet: { ...initialChainAuth },
        },
        currentChain: null,
      });
    }
  },
  
  fetchAdminProfile: async (chain: ChainType) => {
    set({ isLoading: true });
    try {
      const client = multiChainApi.getClient(chain);
      const response = await client.get(API_ENDPOINTS.admin.profile);
      set((state) => ({
        chainAuth: {
          ...state.chainAuth,
          [chain]: {
            admin: response.data,
            isAuthenticated: true,
          },
        },
        isLoading: false,
      }));
    } catch (error) {
      set((state) => ({
        chainAuth: {
          ...state.chainAuth,
          [chain]: {
            admin: null,
            isAuthenticated: false,
          },
        },
        isLoading: false,
      }));
      throw error;
    }
  },
}));